<template>
  <n-modal v-model:show="show"
           :show-icon="false"
           :close-on-esc="false"
           :closable="false"
           :mask-closable="false"
           preset="dialog"
           style="width: 1080px"
           @after-enter="openModal"
           @close="closeImgList">
    <template #header>
      <div class="imgs-header">
        <div class="imgs-header-left">
          <span style="font-size: 18px;font-weight: 500">选择图片</span>
        </div>
        <div class="imgs-header-right">
          <n-button strong secondary size="tiny" @click="closeImgList">
            <n-icon :size="16">
              <svg viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
                <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
                  <g fill="currentColor" fill-rule="nonzero">
                    <path
                        d="M2.08859116,2.2156945 L2.14644661,2.14644661 C2.32001296,1.97288026 2.58943736,1.95359511 2.7843055,2.08859116 L2.85355339,2.14644661 L6,5.293 L9.14644661,2.14644661 C9.34170876,1.95118446 9.65829124,1.95118446 9.85355339,2.14644661 C10.0488155,2.34170876 10.0488155,2.65829124 9.85355339,2.85355339 L6.707,6 L9.85355339,9.14644661 C10.0271197,9.32001296 10.0464049,9.58943736 9.91140884,9.7843055 L9.85355339,9.85355339 C9.67998704,10.0271197 9.41056264,10.0464049 9.2156945,9.91140884 L9.14644661,9.85355339 L6,6.707 L2.85355339,9.85355339 C2.65829124,10.0488155 2.34170876,10.0488155 2.14644661,9.85355339 C1.95118446,9.65829124 1.95118446,9.34170876 2.14644661,9.14644661 L5.293,6 L2.14644661,2.85355339 C1.97288026,2.67998704 1.95359511,2.41056264 2.08859116,2.2156945 L2.14644661,2.14644661 L2.08859116,2.2156945 Z"></path>
                  </g>
                </g>
              </svg>
            </n-icon>
          </n-button>
        </div>
      </div>
    </template>
    <template #default>
      <n-divider style="margin-top: 10px;margin-bottom: 0;"/>
      <div class="material">
        <div class="material-left">
          <div class="material-left-menus">
            <n-menu
                v-model:value="search_img.group"
                :indent="12"
                :options="menuOptions"
                :render-icon="renderIcon"
                :render-label="renderMenuLabel"
                @update:value="changeGroup"
            />
          </div>
          <n-popconfirm :show-icon="false" @positive-click="addGrouping" @negative-click="clearGrouping">
            <template #trigger>
              <n-button>新增分组</n-button>
            </template>
            <n-form ref="grouping_form_ref" inline :model="grouping" :rules="grouping_rules">
              <n-form-item path="name" style="--n-label-height:0">
                <n-input v-model:value="grouping.name" placeholder="分组名称" clearable/>
              </n-form-item>
            </n-form>
          </n-popconfirm>
        </div>
        <n-divider vertical style="margin-top: 0;margin-bottom:0;height: 530px;"/>
        <div class="material-center">
          <div class="material-center-header">
            <div class="material-center-header-upload">
              <custom-upload v-model:value="uploadedFile" ref="cusUpload" multiple insert
                             accept=".jpg,.jpeg,.png,.gif,.svg"
                             upload-type="img" style="height: 0;" :group-id="search_img.group"
                             @finished="getSearchImgs"/>
              <n-button type="primary" @click="uploadImgFile">
                上传图片
                <template #icon>
                  <Upload/>
                </template>
              </n-button>
            </div>
            <div class="material-center-header-search">
              <n-input-group>
                <n-input v-model:value="search_img.name" @keydown.enter.prevent="getSearchImgs"
                         :style="{ width: '80%' }" placeholder="请输入名字" clearable/>
                <n-button type="primary" @click="getSearchImgs">
                  <template #icon>
                    <n-icon>
                      <IosSearch/>
                    </n-icon>
                  </template>
                </n-button>
              </n-input-group>
            </div>
          </div>
          <div class="material-center-img-list">
            <n-spin :show="listLoading" style="height: 445px;">
              <div class="material-center-img-list-container">
                <div class="material-center-img-list-container-item-box" v-for="item in img_data_list"
                     @click.stop="selectImg(item)">
                  <div class="material-center-img-list-container-item-box-remove" v-if="!is_selected(item)"
                       @click.stop="deleteImg(item.src)">
                    <n-icon :size="16">
                      <Close/>
                    </n-icon>
                  </div>
                  <div class="material-center-img-list-container-item-box-img-item"
                       :class="appStore.theme=='light'?'light-imgs':'dark-imgs'">
                    <div class="material-center-img-list-container-item-box-img-item-image">
                      <img :src="imagePreview(item.src)" style="object-fit: contain;width: 100%;height: 100%" alt="">
                    </div>
                    <div class="material-center-img-list-container-item-box-img-item-selected" v-if="is_selected(item)">
                      <n-icon :size="24" color="#fff">
                        <Checkmark/>
                      </n-icon>
                    </div>
                  </div>
                  <div class="material-center-img-list-container-item-box-img-name">
                    {{ item.name }}
                  </div>
                </div>

              </div>
            </n-spin>
          </div>
          <div class="material-center-img-page">
            <n-pagination
                v-model:page="search_img.page"
                :page-size="search_img.page_size"
                :page-count="search_img.page_count"
                size="medium"
                show-quick-jumper @update:page="changePage">
              <template #prefix>
                共 {{ search_img.total }} 条
              </template>
            </n-pagination>
          </div>
        </div>
        <n-divider vertical style="margin-top: 0;margin-bottom:0;height: 530px;"/>
        <div class="material-right">
          <div class="material-right-header">
            <div class="material-right-header-text">已选择&nbsp;{{ selected_imgs.length }}/{{ selectNumber }}</div>
            <div class="material-right-header-btn">
              <n-button text type="primary" @click="()=>(selected_imgs=[])">清空</n-button>
            </div>
          </div>
          <div class="material-right-selected-img">
            <div class="material-right-selected-img-list" v-for="(item,index) in selected_imgs" :key="index"
                 :class="appStore.theme=='light'?'light-imgs':'dark-imgs'">
              <div class="material-right-selected-img-list-remove" @click.stop="removeSelected(item)">
                <n-icon :size="16">
                  <Close/>
                </n-icon>
              </div>
              <div class="material-right-selected-img-list-image">
                <img :src="imagePreview(item)" style="object-fit: contain;width: 100%;height: 100%" alt="">
              </div>
            </div>
          </div>
        </div>
      </div>
      <n-divider style="margin-top: 0;margin-bottom: 10px;"/>
    </template>
    <template #action>
      <n-space>
        <n-button @click="closeImgList">取消</n-button>
        <n-button type="primary" @click="handelConfirmSelection">确认</n-button>
      </n-space>
    </template>
  </n-modal>
</template>

<script setup lang="ts">
import {h, ref, toRaw, toRefs, unref, watch, computed} from 'vue';
import {FormInst, FormRules, MenuOption, NButton, NDropdown, NIcon, useMessage, NInput} from 'naive-ui'
import {Folder, Close, Checkmark} from '@vicons/ionicons5'
import {MoreHorizOutlined} from '@vicons/material'
import {delRequest, getRequest, postPutRequest} from '@/api/data.ts';
import {imagePreview,  uniqueValues, updateStringArray} from '@/util'
import {IosSearch} from '@vicons/ionicons4';
import CustomUpload from '@/components/CustomUpload'

import {UseAppStore} from '@/stores/app.ts';
import {Upload} from '@vicons/tabler'

const props = defineProps({
  show: {
    type: Boolean,
    default: false
  },
  selectNumber: {
    type: Number,
    default: 1
  }
})
const {show, selectNumber} = toRefs(props);
const emits = defineEmits(['update:show', 'selected']);
const message = useMessage();
const appStore = UseAppStore();
//上传图片组件
const cusUpload = ref<any>()
const uploadedFile = ref<string | null | string[]>([])


watch(() => unref(show),
    (up) => {
      if (!up) emits("update:show", false)
    });
const listLoading = ref<boolean>(false);
const search_img = ref({
  name: '',
  page: 1,
  page_size: 15,
  group: '-1',
  total: 0,
  page_count: 0,
});
//图片列表
const img_data_list = ref<{ id: number, name: string, src: string, groupId: number | null }[]>([]);

watch(() => unref(img_data_list),
    (data) => {
      const data_length = toRaw(data).length;
      const page = search_img.value.page;
      if (data_length === 0 && page != 1) {
        search_img.value.page = page - 1;
        getSearchImgs();
      }
    }
);
//分组数据
const menuOptions = ref<MenuOption[]>([
  {
    label: '全部',
    key: '-1',
  },
  {
    label: '未分组',
    key: '0',
  },
]);
//分组处理
const grouping_form_ref = ref<FormInst | null>(null);
const grouping = ref<{ id: number, name: string }>({
  id: 0,
  name: ''
});
const grouping_rules = ref<FormRules>({
  name: {
    required: true,
    trigger: ['blur', 'input'],
    message: '请填写分组名称',
  }
});
//已选中图片
const selected_imgs = ref<string[]>([]);
//已选中
const is_selected = computed(() => (item: any) => {
  return selected_imgs.value.includes(item.src);
});
//取消新增分组
const clearGrouping = () => {
  setTimeout(function () {
    grouping.value.name = '';
  }, 500)
}
//新增分组
const addGrouping = (e: MouseEvent) => {
  e.preventDefault();
  grouping_form_ref.value?.validate((errors) => {
    if (!errors) {
      const url = grouping.value.id ? 'sys/edit_img_group' : 'sys/add_img_group';
      postPutRequest(url, grouping.value, grouping.value.id ? 'PUT' : 'POST').then((result: ResponseResult) => {
        message.create(result.message, {
          type: result.code === 200 ? 'success' : 'error'
        });
        if (result.code === 200) {
          menuOptions.value.push(result.data);
          grouping.value.name = '';
        }
      })
    } else {
      const msg: string | any = errors[0][0].message;
      message.error(msg);
    }
  })
}
const openModal = () => {
  selected_imgs.value = [];
  getGroupList();
  getSearchImgs();
}
//分组列表
const getGroupList = async () => {
  await getRequest('sys/img_group_list').then((result: ResponseResult) => {
    const {data} = result;
    menuOptions.value = uniqueValues(toRaw(menuOptions.value), data);
  })
}
//分组图标
const renderIcon = () => {
  return h(NIcon, {
    color: 'color(srgb 0.9988 0.9139 0.5848)',
  }, {default: () => h(Folder)})
}
const renderMenuLabel = (option: MenuOption) => {
  if (parseInt(<string>option.key) > 0) {

    return h('div', {
      style: {
        display: 'flex'
      }
    }, {
      default: () => (
          [
            h('div', {
              style: {
                display: 'flex',
                justifyContent: 'flex-start',
                flex: 1,
              }
            }, {
              default: () => (option.edit ? [h(NInput, {
                // @ts-ignore
                value: option.label,
                onUpdateValue(v: any) {
                  option.label = v
                },
                onBlur: () => {
                  option.edit = false;
                  editGroupName(option)
                },
              })] : option.label)
            }),
            h('div', {
              style: {
                display: 'flex',
                justifyContent: 'flex-end',
              }
            }, {
              default: () => ([h(NDropdown, {
                    trigger: 'hover',
                    size: 'small',
                    showArrow: true,
                    options: [
                      {
                        label: '重命名',
                        key: 'edit',
                      }, {
                        label: '删除',
                        key: 'del',
                      }
                    ],
                    onSelect: (key: string | number) => {
                      switch (key) {
                        case 'del':
                          deleteGroup(option);
                          break;
                        case 'edit':
                          option.edit = true;
                          break;
                      }
                    },
                  }, {
                    default: () => (h(NButton, {text: true}, {icon: () => h(NIcon, {}, {default: () => h(MoreHorizOutlined)})}))
                  }
              )])
            })
          ])
    })
  }
  return option.label as string
}

const deleteGroup = async (option: MenuOption) => {
  await delRequest('sys/del_img_group', option.key).then((result: ResponseResult) => {
    message.create(result.message, {
      type: result.code === 200 ? 'success' : 'error'
    });
    if (result.code === 200) {
      menuOptions.value = menuOptions.value.filter((item: any) => {
        return item.key != option.key
      });
    }
  })
}
const editGroupName = async (option: MenuOption) => {
  await postPutRequest('sys/edit_img_group', {id: option.key, name: option.label}, "PUT");
}
//图片列表
const getSearchImgs = async () => {
  listLoading.value = true;
  await getRequest('sys/img_list', {
    page: search_img.value.page,
    pageSize: search_img.value.page_size,
    group: search_img.value.group,
    name: search_img.value.name
  }).then((result: ResponseResult) => {
    img_data_list.value = result.data.list;
    search_img.value.total = result.data.total;
    search_img.value.page_count = result.data.totalPage;
    listLoading.value = false;
  })
}

//上传图片
const uploadImgFile = () => {
  cusUpload.value.click()
}

const changeGroup = (key: string) => {
  search_img.value.group = key;
  search_img.value.page = 1;
  search_img.value.name = '';
  getSearchImgs();
}
const changePage = (page: number) => {
  search_img.value.page = page;
  getSearchImgs();
}
//删除图片
const deleteImg = (id: number | string) => {
  delRequest('sys/img_del', id).then((result: ResponseResult) => {
    if (result.code === 200) {
      message.success(result.message, {
        duration: 1500,
        onLeave() {
          getSearchImgs();
        }
      })
    } else {
      message.error(result.message);
    }
  })
}
//选择图片
const selectImg = (item: any) => {
  const select = item.src;
  const already_selected = selected_imgs.value.includes(select);
  if (selectNumber.value === 1) {
    selected_imgs.value = [item.src]
  } else if (selectNumber.value > 1 && selected_imgs.value.length < selectNumber.value) {
    selected_imgs.value = updateStringArray(selected_imgs.value, select);
  } else if (selectNumber.value > 1 && already_selected) {
    selected_imgs.value = updateStringArray(selected_imgs.value, select);
  } else {
    message.warning('已达到选择上限');
    return;
  }
}
//删除已选中的图片
const removeSelected = (element: string) => {
  selected_imgs.value = selected_imgs.value.filter(item => item !== element);
}

//确定选择
const handelConfirmSelection = () => {
  emits("selected", toRaw(unref(selected_imgs)));
  emits("update:show", !unref(show));
}
const closeImgList = () => {
  emits("update:show", !unref(show));
  setTimeout(function () {
    selected_imgs.value = [];
  }, 500)
}
</script>

<style scoped lang="scss">
@import 'index.scss';
</style>